﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Windows.Forms;
using PayexpDAL;
using Utilities;
using System.Globalization;
using ExcelHandler;
using PayexpUserControls;

namespace Moneymatters
{
    public partial class MainForm
    {
        #region Private Fields
        private bool _isPopulating;
        private Dictionary<int, TransactionMaster> _currentlyEditedTransactionMasterListMap = new Dictionary<int, TransactionMaster>();

        private bool _resultsExistReconcileView = false;
        private int _currentTotalNumberOfRecordsReconcileView = 0;
        private int _currentPageNumberReconcileView = 0;
        private int _currentLastPageNumberReconcileView = 0;
        private int _currentRecordsPerPageToUseReconcileView = 0;
        private bool _resultRefreshNeededReconcileView;
        private FilterCriteria _currentFilterCriteriaReconcileView;
        private Dictionary<int, List<TransactionMaster>> _pagedResultReconcileView = new Dictionary<int, List<TransactionMaster>>();
        private Dictionary<int, List<DataGridViewRow>> _pagedResultDGViewRowsReconcileView = new Dictionary<int, List<DataGridViewRow>>();
        #endregion Private Fields

        #region Properties
        #endregion Properties

        #region Private Methods

        private void buttonPreviousReconcile_Click(object sender, EventArgs e)
        {
            if (this._resultRefreshNeededReconcileView && this.dataGridViewTransactions.Rows.Count != 0)
            {
                DisplayRefreshViewMessage();
                return;
            }

            this.Cursor = Cursors.WaitCursor;
            this._currentPageNumberReconcileView = this._currentPageNumberReconcileView - 1;
            if (this._currentPageNumberReconcileView < 0)
            {
                this.buttonPreviousReconcile.Enabled = false;
            }
            else if (_currentPageNumberReconcileView == 0)
            {
                this.buttonPreviousReconcile.Enabled = false;
                FetchAndDisplayPagedResultsReconcileView();
            }
            else
            {
                FetchAndDisplayPagedResultsReconcileView();
            }

            this.buttonNextReconcile.Enabled = true;
            this.Cursor = Cursors.Arrow;
        }

        private void buttonNextReconcile_Click(object sender, EventArgs e)
        {
            if (this._resultRefreshNeededReconcileView && this.dataGridViewTransactions.Rows.Count != 0)
            {
                DisplayRefreshViewMessage();
                return;
            }

            this.Cursor = Cursors.WaitCursor;
            this._currentPageNumberReconcileView = this._currentPageNumberReconcileView + 1;
            this.buttonPreviousReconcile.Enabled = true;

            // TO DO
             FetchAndDisplayPagedResultsReconcileView();
            
            if ((this._currentPageNumberReconcileView + 1) == this._currentLastPageNumberReconcileView)
            {
                this.buttonNextReconcile.Enabled = false;
            }
            this.Cursor = Cursors.Arrow;
        }

        private void buttonExpandReconcileFilter_Click(object sender, EventArgs e)
        {
            this.filterControlReconcile.Size = new Size(this.filterControlReconcile.Width, 240);
            this.filterControlReconcile.Location = new Point(this.filterControlReconcile.Location.X, 40);

            this.dataGridViewTransactions.Size = new Size(this.dataGridViewTransactions.Width, 295);
            this.dataGridViewTransactions.Location = new Point(this.dataGridViewTransactions.Location.X, 280);
        }

        private void buttonCollapseReconcileFilter_Click(object sender, EventArgs e)
        {
            this.filterControlReconcile.Size = new Size(this.filterControlReconcile.Width, 18);
            this.filterControlReconcile.Location = new Point(this.filterControlReconcile.Location.X, 40);

            this.dataGridViewTransactions.Size = new Size(this.dataGridViewTransactions.Width, 510);
            this.dataGridViewTransactions.Location = new Point(this.dataGridViewTransactions.Location.X, 65);
        }

        private void buttonDisplayReconcile_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            ResetReconcileView();

            this._currentFilterCriteriaReconcileView = this.filterControlReconcile.GetFilterCriteria();
            if (_currentFilterCriteriaReconcileView.HasError)
            {
                MessageBox.Show(string.Join(Environment.NewLine, _currentFilterCriteriaReconcileView.ValidationErrorList.ToArray()), "Please correct your filter criteria", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                this._currentRecordsPerPageToUseReconcileView = this.NumberOfRecordsPerPage;
                // TO DO
                FetchAndDisplayPagedResultsReconcileView();
            }
            this.Cursor = Cursors.Arrow;
        }

        private void buttonEditSelectedTransactionReconcile_Click(object sender, EventArgs e)
        {
            if (this._resultRefreshNeededReconcileView && this.dataGridViewTransactions.Rows.Count != 0)
            {
                DisplayRefreshViewMessage();
                return;
            }
            EditSelected(this.dataGridViewTransactions);
        }

        private void buttonExportReconcile_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            // This will never be needed..still.
            if (!this.filterControlReconcile.OnlyPettyCashFilterCriteriaSelected)
            {
                ResetReconcileView();
            }

            this._currentFilterCriteriaReconcileView = this.filterControlReconcile.GetFilterCriteria();
            if (_currentFilterCriteriaReconcileView.HasError)
            {
                MessageBox.Show(string.Join(Environment.NewLine, _currentFilterCriteriaReconcileView.ValidationErrorList.ToArray()), "Please correct your filter criteria", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                int numberOfRecordsPerPageToUse = this.NumberOfRecordsPerPage;
                ExportFilteredResult(this._currentFilterCriteriaReconcileView, this.progressBarExportFromReconcileView, numberOfRecordsPerPageToUse);
                ResetReconcileView();
            }
            this.Cursor = Cursors.Arrow;
        }

        private void buttonViewHistoryReconcile_Click(object sender, EventArgs e)
        {
            if (this._resultRefreshNeededReconcileView && this.dataGridViewTransactions.Rows.Count != 0)
            {
                DisplayRefreshViewMessage();
                return;
            }
            ViewHistory(this.dataGridViewTransactions);
        }
        
        private void ResetReconcileView()
        {
            this._pagedResultReconcileView.Clear();
            this._pagedResultDGViewRowsReconcileView.Clear();
            this.dataGridViewTransactions.Rows.Clear();
            this._currentTotalNumberOfRecordsReconcileView = 0;
            this._currentPageNumberReconcileView = 0;
            this._currentLastPageNumberReconcileView = 0;
            this._currentFilterCriteriaReconcileView = null;
            this.buttonPreviousReconcile.Enabled = false;
            this.buttonNextReconcile.Enabled = true;
            this._resultsExistReconcileView = false;
            this.labelCurentPageNumberDetailsReconcile.Text = string.Empty;
            this.filterControlReconcile.TransactionMasterIdList.Clear();
            this._resultRefreshNeededReconcileView = false;
            this._isPopulating = false;
            this._currentlyEditedTransactionMasterListMap.Clear();
        }

        private void checkBoxOnlyUnreconciledRecordsReconcile_CheckedChanged(object sender, EventArgs e)
        {
            this.filterControlReconcile.OnlyUnreconciledRecords = this.checkBoxOnlyUnreconciledRecordsReconcile.Checked;
            if (this.checkBoxOnlyUnreconciledRecordsReconcile.Checked && this.checkBoxOnlyReconciledRecordsReconcile.Checked)
            {
                this.checkBoxOnlyReconciledRecordsReconcile.Checked = false;
            }
        }

        private void checkBoxOnlyReconciledRecordsReconcile_CheckedChanged(object sender, EventArgs e)
        {
            this.filterControlReconcile.OnlyReconciledRecords = this.checkBoxOnlyReconciledRecordsReconcile.Checked;
            if (this.checkBoxOnlyReconciledRecordsReconcile.Checked && this.checkBoxOnlyUnreconciledRecordsReconcile.Checked)
            {
                this.checkBoxOnlyUnreconciledRecordsReconcile.Checked = false;
            }
        }

        private void checkBoxOnlyIncomeRecordsReconcile_CheckedChanged(object sender, EventArgs e)
        {
            this.filterControlReconcile.OnlyIncomeRecords = this.checkBoxOnlyIncomeRecordsReconcile.Checked;
            if (this.checkBoxOnlyIncomeRecordsReconcile.Checked && this.checkBoxOnlyExpenseRecordsReconcile.Checked)
            {
                this.checkBoxOnlyExpenseRecordsReconcile.Checked = false;
            }
        }

        private void checkBoxOnlyExpenseRecordsReconcile_CheckedChanged(object sender, EventArgs e)
        {
            this.filterControlReconcile.OnlyExpenseRecords = this.checkBoxOnlyExpenseRecordsReconcile.Checked;
            if (this.checkBoxOnlyExpenseRecordsReconcile.Checked && this.checkBoxOnlyIncomeRecordsReconcile.Checked)
            {
                this.checkBoxOnlyIncomeRecordsReconcile.Checked = false;
            }
        }

        private void buttonApplyTransactionBankToAllExpense_Click(object sender, EventArgs e)
        {
            if (this._resultRefreshNeededReconcileView && this.dataGridViewTransactions.Rows.Count != 0)
            {
                DisplayRefreshViewMessage();
                return;
            }
            SetTransactionBank(false);
        }

        private void buttonApplyTransactionBankToAllIncome_Click(object sender, EventArgs e)
        {
            if (this._resultRefreshNeededReconcileView && this.dataGridViewTransactions.Rows.Count != 0)
            {
                DisplayRefreshViewMessage();
                return;
            }
            SetTransactionBank(true);
        }

        private void buttonClearReconcileGrid_Click(object sender, EventArgs e)
        {
            ResetReconcileView();
        }

        private void SetTransactionBank(bool setForIncomeRecords)
        {
            foreach (DataGridViewRow dataGridViewRow in this.dataGridViewTransactions.Rows)
            {
                if (dataGridViewRow.Tag as TransactionMaster == null)
                {
                    continue;
                }

                TransactionMaster transactionMaster = (TransactionMaster)dataGridViewRow.Tag;
                if (setForIncomeRecords && !transactionMaster.Head.Equals("head_income"))
                {
                    continue;
                }

                if (!setForIncomeRecords && transactionMaster.Head.Equals("head_income"))
                {
                    continue;
                }

                // do not reconcile cash expense transactions
                // do not change the bank on cheque expense transactions
                if (
                    (transactionMaster.Head.Equals("head_expense") && transactionMaster.TransactionModeValue.Equals("transaction_mode_cash")) ||
                    (transactionMaster.Head.Equals("head_expense") && transactionMaster.TransactionModeValue.Equals("transaction_mode_cheque"))
                   )
                {
                    continue;
                }

                // set transaction bank 
                ComboBoxItem selectedItem = (ComboBoxItem)this.comboBoxBulkBankAccountSettingSelector.SelectedItem;
                BankAccount selectedBankAccount = (BankAccount)selectedItem.Value;
                DataGridViewComboBoxCell reconciliationBankCell = (DataGridViewComboBoxCell)dataGridViewRow.Cells[UIConstants.TransactionsGrid.TransactionBankIndex];
                if (selectedBankAccount != null)
                {
                    transactionMaster.BankAccountsId = selectedBankAccount.Id;
                    reconciliationBankCell.Value = selectedBankAccount.BankDisplayName;
                }
                else
                {
                    transactionMaster.BankAccountsId = null;
                }

            }
        }

        private void Reconcile()
        {
            if (this._currentlyEditedTransactionMasterListMap.Count == 0)
            {
                MessageBox.Show("You do not seem to have mande any changes to save.", "No Changes", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            List<TransactionMaster> transactionListToReconcile = new List<TransactionMaster>();
            foreach (TransactionMaster transactionMaster in this._currentlyEditedTransactionMasterListMap.Values)
            {
                // do not reconcile cash expense transactions
                if (transactionMaster.Head.Equals("head_expense") && transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
                {
                    continue;
                }

                transactionMaster.UpdatedBy = LoginForm.LoggedInUserName;
                transactionMaster.UpdatedDate = DateTime.Now;
                transactionListToReconcile.Add(transactionMaster);
            }

            try
            {
                if (transactionListToReconcile.Count > 0)
                {
                    this.dataAccessHandlerCommonInstance.ReconcileTransactions(transactionListToReconcile, MainForm.Context);
                    this.dataAccessHandlerCommonInstance.UpdateBankAccountDetailsAndStatistics(MainForm.Context);
                    this.Cursor = Cursors.Arrow;
                    MessageBox.Show("Your data was saved sucessfully.", "Save successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    ResetReconcileView();
                    this._resultRefreshNeededBankStatementsView = true;
                }
            }
            catch
            {
                this.Cursor = Cursors.Arrow;
                MessageBox.Show("There was a problem saving your data. Please try again or contact your administrator.", "Save failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void buttonUpdateBankDate_Click(object sender, EventArgs e)
        {
            if (this._resultRefreshNeededReconcileView && this.dataGridViewTransactions.Rows.Count != 0)
            {
                DisplayRefreshViewMessage();
                return;
            }
            Reconcile();

            // clear the main panel
            this.buttonRefresh_Click(null, null);

            #region ORIGINAL CODE
            //List<TransactionMaster> transactionListToReconcile = new List<TransactionMaster>();
            //foreach (DataGridViewRow row in this.dataGridViewTransactions.Rows)
            //{
            //    if (row.Tag as TransactionMaster == null)
            //    {
            //        continue;
            //    }

            //    TransactionMaster transactionMaster = (TransactionMaster)row.Tag;
            //    // do not reconcile cash expense transactions
            //    if (transactionMaster.Head.Equals("head_expense") && transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
            //    {
            //        continue;
            //    }


            //    transactionMaster.UpdatedBy = LoginForm.LoggedInUserName;
            //    transactionMaster.UpdatedDate = DateTime.Now;

            //    transactionListToReconcile.Add(transactionMaster);

            //    // set transaction bank date
            //    //if (row.Cells[1].Tag == null)
            //    if (row.Cells[UIConstants.TransactionsGrid.BankDateIndex].Tag == null)
            //    {
            //        transactionMaster.BankDate = null;
            //    }
            //    else
            //    {
            //        try
            //        {
            //            //DateTime selectedBankDate = (DateTime)row.Cells[1].Tag;
            //            DateTime selectedBankDate = (DateTime)row.Cells[UIConstants.TransactionsGrid.BankDateIndex].Tag;
            //            transactionMaster.BankDate = selectedBankDate;

            //        }
            //        catch
            //        {
            //            transactionMaster.BankDate = null;
            //        }
            //    }

            //    // set transaction bank 
            //    //DataGridViewComboBoxCell transactionBank = (DataGridViewComboBoxCell)row.Cells[4];
            //    DataGridViewComboBoxCell transactionBank = (DataGridViewComboBoxCell)row.Cells[UIConstants.TransactionsGrid.TransactionBankIndex];
            //    string selectedBank = transactionBank.Value.ToString();
            //    BankAccount selectedBankAccount = ((List<BankAccount>)transactionBank.DataSource).Where(t => t.BankDisplayName.Equals(selectedBank)).FirstOrDefault();
            //    if (selectedBankAccount != null)
            //    {
            //        transactionMaster.BankAccountsId = selectedBankAccount.Id;
            //    }
            //    else
            //    {
            //        transactionMaster.BankAccountsId = null;
            //    }
            //}



            //try
            //{
            //    if (transactionListToReconcile.Count > 0)
            //    {
            //        new DataAccessHandler().ReconcileTransactions(transactionListToReconcile, MainForm.Context);
            //        this.Cursor = Cursors.Arrow;
            //        MessageBox.Show("Your data was saved sucessfully", "Save successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //        buttonClearResultsGrid_Click(null, null);
            //    }
            //}
            //catch
            //{
            //    this.Cursor = Cursors.Arrow;
            //    MessageBox.Show("There was a problem saving your data. Please try again or contact your administrator.", "Save failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //}
            #endregion ORIGINAL CODE
        }

        private void dataGridViewTransactions_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (!this._isPopulating && this.dataGridViewTransactions.Rows[e.RowIndex].Tag != null)
            {
                DataGridViewRow row = this.dataGridViewTransactions.Rows[e.RowIndex];
                if (row.Tag != null)
                {
                    TransactionMaster editedTransactionMaster = (TransactionMaster)row.Tag;

                    // do not reconcile cash expense transactions
                    if (editedTransactionMaster.Head.Equals("head_expense") && editedTransactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
                    {
                        return;
                    }

                    // set transaction bank date
                    if (row.Cells[UIConstants.TransactionsGrid.BankDateIndex].Tag == null)
                    {
                        editedTransactionMaster.BankDate = null;
                    }
                    else
                    {
                        try
                        {
                            DateTime selectedBankDate = (DateTime)row.Cells[UIConstants.TransactionsGrid.BankDateIndex].Tag;
                            editedTransactionMaster.BankDate = selectedBankDate;
                        }
                        catch
                        {
                            editedTransactionMaster.BankDate = null;
                        }
                    }

                    // set transaction bank 
                    DataGridViewComboBoxCell transactionBank = (DataGridViewComboBoxCell)row.Cells[UIConstants.TransactionsGrid.TransactionBankIndex];
                    string selectedBank = transactionBank.Value.ToString();
                    BankAccount selectedBankAccount = ((List<BankAccount>)transactionBank.DataSource).Where(t => t.BankDisplayName.Equals(selectedBank)).FirstOrDefault();
                    if (selectedBankAccount != null)
                    {
                        editedTransactionMaster.BankAccountsId = selectedBankAccount.Id;
                    }
                    else
                    {
                        editedTransactionMaster.BankAccountsId = null;
                    }


                    if (!_currentlyEditedTransactionMasterListMap.ContainsKey(editedTransactionMaster.Id))
                    {
                        _currentlyEditedTransactionMasterListMap.Add(editedTransactionMaster.Id, editedTransactionMaster);
                    }
                }
            }
        }

        private void dataGridViewTransactions_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView gridView = (DataGridView)sender;
            if (gridView.SelectedCells.Count > 0)
            {
                if (gridView.SelectedCells[0] as DataGridViewButtonCell != null)
                {
                    DataGridViewButtonCell dataGridViewButtonCell = (DataGridViewButtonCell)gridView.SelectedCells[0];
                    TransactionMaster transactionMaster = (TransactionMaster)dataGridViewButtonCell.OwningRow.Tag;
                    if (transactionMaster.Head.Equals("head_expense") && transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
                    {
                        return;
                    }

                    if (dataGridViewButtonCell.Tag != null)
                    {
                        if (dataGridViewButtonCell.Tag.ToString().Equals("bankDateSelectButton"))
                        {
                            DataGridViewTextBoxCell transactionDateCell =
                                (DataGridViewTextBoxCell)dataGridViewButtonCell.OwningRow.Cells[UIConstants.TransactionsGrid.TransactionDateIndex];

                            DataGridViewTextBoxCell bankDateCell =
                                    (DataGridViewTextBoxCell)dataGridViewButtonCell.OwningRow.Cells[UIConstants.TransactionsGrid.BankDateIndex];

                            DateTime? transactionDate = null;
                            if (bankDateCell.Tag != null)
                            {
                                transactionDate = (DateTime)bankDateCell.Tag;
                            }
                            else if (transactionDateCell.Tag != null)
                            {
                                transactionDate = (DateTime)transactionDateCell.Tag;
                            }

                            DateTimePickerForm form = new DateTimePickerForm(transactionDate);

                            int maxY = this.DesktopLocation.Y + this.Size.Height;


                            // this works but then the dialog goes out of the screen at times when we select lower rows :(
                            form.StartPosition = FormStartPosition.Manual;
                            //form.DesktopLocation = gridView.PointToScreen(
                            //            gridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Location);


                            Point cellPoint = gridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Location;

                            if (cellPoint.Y + form.Size.Height + 300 > maxY)
                            {
                                Point newPoint = new Point(cellPoint.X, (maxY - 350 - form.Size.Height));
                                form.DesktopLocation = gridView.PointToScreen(newPoint);
                            }
                            else
                            {
                                form.DesktopLocation = gridView.PointToScreen(cellPoint);
                            }

                            DialogResult dr = form.ShowDialog();
                            if (dr == System.Windows.Forms.DialogResult.OK)
                            {
                                bankDateCell.Tag = form.SelectedDateTime;
                                bankDateCell.Value = form.SelectedDateTime.Get_DD_MONTH_YY_DateString();
                            }

                        }
                        else if (dataGridViewButtonCell.Tag.ToString().Equals("bankDateClearButton"))
                        {
                            DataGridViewTextBoxCell bankDateCell =
                                (DataGridViewTextBoxCell)dataGridViewButtonCell.OwningRow.Cells[UIConstants.TransactionsGrid.BankDateIndex];

                            bankDateCell.Tag = null;
                            bankDateCell.Value = string.Empty;
                        }
                    }
                }


                #region NOT NEEDED ANYMORE
                // WE DO NOT SHOW VOUCHER AND RECEIPT NUMBER ANY MORE HERE..HENCE COMMENTING

                //if (gridView.SelectedCells[0] as DataGridViewLinkCell != null)
                //{
                //    DataGridViewLinkCell dataGridViewLinkCell = (DataGridViewLinkCell)gridView.SelectedCells[0];
                //    if (dataGridViewLinkCell.Tag != null)
                //    {
                //        if (dataGridViewLinkCell.Tag.ToString().Equals("voucherReceiptNumber"))
                //        {
                //            // call pdf method here
                //            DataGridViewRow selectedRow = gridView.Rows[dataGridViewLinkCell.RowIndex];
                //            try
                //            {
                //                PDFCreator.CreateVoucher((TransactionMaster)selectedRow.Tag);
                //            }
                //            catch
                //            {
                //                MessageBox.Show("There was a problem generating your voucher/ receipt. Please try again. If the problem persists, please contact your administrator to have this fixed.", "Could not generate document", MessageBoxButtons.OK, MessageBoxIcon.Error);
                //                return;
                //            }

                //        }
                //        else
                //        {
                //            NarrationDialog narration = new NarrationDialog(dataGridViewLinkCell.Tag.ToString(), true);
                //            narration.ShowDialog();
                //        }
                //    }
                //}
                #endregion NOT NEEDeD ANYMORE
            }
        }

        private void buttonUnreconciledLatestTop_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            //this.groupBoxDateFilters.Enabled = false;
            //this.groupBoxAmountRangeFilters.Enabled = false;
            //this.groupBoxChequeNumberRangeFilters.Enabled = false;
            //this.groupBoxHeadDetailsFilters.Enabled = false;
            //this.groupBoxNarrationFilters.Enabled = false;

            //DataAccessHandler dataAccessHandler = new DataAccessHandler();
            var unreconciledList = this.dataAccessHandlerCommonInstance.GetUnreconciledTransactionMasterList(false, MainForm.Context);

            if (unreconciledList.Count > 0)
            {
                // TO DO LATER
                //DisplayExistingTransactions(unreconciledList);
                labelNumberOfRecords.Text = "(" + unreconciledList.Count.ToString() + ")";
            }
            else
            {
                MessageBox.Show("No  unreconciled records found.", "No Records", MessageBoxButtons.OK, MessageBoxIcon.Information);
                buttonClearReconcileGrid.PerformClick();
                labelNumberOfRecords.Text = string.Empty;
            }

            this.Cursor = Cursors.Arrow;
        }

        private void buttonUnreconciledOldestTop_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            //this.groupBoxDateFilters.Enabled = false;
            //this.groupBoxAmountRangeFilters.Enabled = false;
            //this.groupBoxChequeNumberRangeFilters.Enabled = false;
            //this.groupBoxHeadDetailsFilters.Enabled = false;
            //this.groupBoxNarrationFilters.Enabled = false;

            //DataAccessHandler dataAccessHandler = new DataAccessHandler();
            var unreconciledList = this.dataAccessHandlerCommonInstance.GetUnreconciledTransactionMasterList(true, MainForm.Context);

            if (unreconciledList.Count > 0)
            {
                // TO DO LATER
                //DisplayExistingTransactions(unreconciledList);
                labelNumberOfRecords.Text = "(" + unreconciledList.Count.ToString() + ")";
            }
            else
            {
                MessageBox.Show("No  unreconciled records found.", "No Records", MessageBoxButtons.OK, MessageBoxIcon.Information);
                buttonClearReconcileGrid.PerformClick();
                labelNumberOfRecords.Text = string.Empty;
            }

            this.Cursor = Cursors.Arrow;
        }
        
        /// <summary>
        /// just ensures the background color does not change like mad :)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridViewTransactions_Click(object sender, EventArgs e)
        {
            DataGridView dataGridView = (DataGridView)sender;

            if (this.dataGridViewTransactions.SelectedRows.Count == 0)
            {
                return;
            }

            DataGridViewRow selectedRow = dataGridView.SelectedRows[0]; // multi select not considered
            TransactionMaster transactionMaster = (TransactionMaster)selectedRow.Tag;

            selectedRow.DefaultCellStyle.SelectionBackColor = selectedRow.DefaultCellStyle.BackColor;
        }

        private void PopulateReconcileGrid(List<TransactionMaster> transactionMasterList)
        {
            this.dataGridViewTransactions.Rows.Clear();

            try
            {
                this._isPopulating = true;

                if (_pagedResultDGViewRowsReconcileView.ContainsKey(this._currentPageNumberReconcileView))
                {
                    foreach (DataGridViewRow dgViewRow in _pagedResultDGViewRowsReconcileView[this._currentPageNumberReconcileView])
                    {
                        this.dataGridViewTransactions.Rows.Add(dgViewRow);
                    }
                }
                else
                {
                    List<DataGridViewRow> forCaching = new List<DataGridViewRow>();
                    foreach (TransactionMaster transactionMasterEntry in transactionMasterList)
                    {
                        this.dataGridViewTransactions.Rows.Add();
                        int newRowIndex = this.dataGridViewTransactions.Rows.Count - 1;
                        DataGridViewRow newRow = this.dataGridViewTransactions.Rows[newRowIndex];

                        if (transactionMasterEntry.Head.Equals("head_expense"))
                        {
                            newRow.DefaultCellStyle.BackColor = Color.PaleVioletRed;
                        }
                        else
                        {
                            newRow.DefaultCellStyle.BackColor = Color.LightGreen;
                        }

                        newRow.Cells["transactionDate"].Value = transactionMasterEntry.TransactionDate.Get_DD_MONTH_YY_DateString();//.ToShortDateString();
                        newRow.Cells["transactionDate"].Tag = transactionMasterEntry.TransactionDate;

                        if (transactionMasterEntry.BankDate.HasValue)
                        {
                            newRow.Cells["bankDate"].Value = transactionMasterEntry.BankDate.Value.Get_DD_MONTH_YY_DateString();
                            newRow.Cells["bankDate"].Tag = transactionMasterEntry.BankDate.Value;
                        }
                        else
                        {
                            newRow.Cells["bankDate"].Tag = null;
                        }

                        newRow.Cells["bankDateSelectButton"].Value = "Select";
                        newRow.Cells["bankDateSelectButton"].Tag = "bankDateSelectButton";


                        newRow.Cells["bankDateClearButton"].Value = "Clear";
                        newRow.Cells["bankDateClearButton"].Tag = "bankDateClearButton";


                        //List<StaticList> staticListEntries = new DataAccessHandler().GetListValuesByCode(new List<string>() { transactionMasterEntry.Head }, MainForm.Context);


                        DataGridViewComboBoxCell reconciliationBankCell = (DataGridViewComboBoxCell)newRow.Cells["reconciliationBank"];
                        if (transactionMasterEntry.BankAccountsId.HasValue)
                        {
                            try
                            {
                                reconciliationBankCell.DataSource = SettingsAndStaticListLoader.BankAccountList;
                                reconciliationBankCell.ValueMember = "BankDisplayName";
                                int index = SettingsAndStaticListLoader.BankAccountList.IndexOf(SettingsAndStaticListLoader.BankAccountList.Where(t => t.Id.Equals(transactionMasterEntry.BankAccountsId.Value)).FirstOrDefault());
                                reconciliationBankCell.Value = SettingsAndStaticListLoader.BankAccountList[index].BankDisplayName;
                            }
                            catch { }
                        }


                        // this is because a cheque from one of the banks has already been given. we can no longer change the bank :)
                        if (transactionMasterEntry.Head.Equals("head_expense") &&
                                (transactionMasterEntry.TransactionModeValue.Equals("transaction_mode_cheque") ||
                                 transactionMasterEntry.TransactionModeValue.Equals("transaction_mode_pettycashwithdrawal")
                                )
                           )
                        {
                            newRow.Cells["reconciliationBank"].ReadOnly = true;
                        }

                        // special case for petty cash expenses because they should not be reconciled even accidentally.
                        // deleted transactions too cannot be reconciled :)
                        if (!transactionMasterEntry.IsActive ||
                            (transactionMasterEntry.Head.Equals("head_expense") && transactionMasterEntry.TransactionModeValue.Equals("transaction_mode_cash"))
                           )
                        {
                            newRow.Cells["reconciliationBank"].ReadOnly = true;
                            newRow.Cells["bankDateSelectButton"].ReadOnly = false;
                            newRow.Cells["bankDateClearButton"].ReadOnly = true;
                            newRow.Cells["bankDate"].ReadOnly = true;
                        }

                        newRow.Cells["transactionMode"].Value = transactionMasterEntry.TransactionModeValueDisplayName;

                        //staticListEntries = new DataAccessHandler().GetListValuesByCode(new List<string>() { transactionMasterEntry.TransactionModeValue }, MainForm.Context);
                        //if (staticListEntries.Count > 0)
                        //{
                        //    newRow.Cells["transactionMode"].Value = staticListEntries.First().ListItemValue;
                        //}

                        newRow.Cells["amount"].Value = transactionMasterEntry.TransactionAmount;

                        //List<TransactionType> temp = GetTransactionType(transactionMasterEntry.HeadDetailsHierarchyIdList);
                        //temp = ArrangeItems(temp);
                        //if (temp.Count > 0)
                        //{
                        //    newRow.Cells["headDetails"].Value = temp.Last().Name;
                        //    string headDetailsComplete = string.Join("-->", temp.Select(t => t.Name).ToArray());
                        //    newRow.Cells["headDetails"].ToolTipText = headDetailsComplete;
                        //}

                        newRow.Cells["headDetails"].Value = transactionMasterEntry.GetHeadDetailsComplete();


                        //if (!string.IsNullOrEmpty(transactionMasterEntry.Narration))
                        //{
                        //    string narration = transactionMasterEntry.Narration.Replace(Environment.NewLine, string.Empty);
                        //    newRow.Cells["narration"].Value = narration;
                        //    newRow.Cells["narration"].Tag = transactionMasterEntry.Narration;
                        //}

                        newRow.Cells["narration"].Value = transactionMasterEntry.Narration;

                        newRow.Cells["consolidatedChequeDetails"].Value = transactionMasterEntry.ConsolidateChequeDetails;

                        if (!transactionMasterEntry.IsActive)
                        {
                            newRow.DefaultCellStyle.ForeColor = Color.Red;
                            newRow.Frozen = true;
                        }

                        // Display current Balance
                        if (transactionMasterEntry.CurrentBalance > 0)
                        {
                            newRow.Cells["currentBalance"].Value = transactionMasterEntry.CurrentBalance;
                        }

                        newRow.Cells["expenseApproverDisplayList"].Value = transactionMasterEntry.ExpenseApprovalDetails;

                        foreach (DataGridViewCell cell in newRow.Cells)
                        {
                            cell.Style.WrapMode = DataGridViewTriState.True;
                        }

                        if (!transactionMasterEntry.IsActive)
                        {
                            DataGridViewCellStyle style = new DataGridViewCellStyle();
                            style.Font = new Font(dataGridViewTransactions.Font.OriginalFontName, dataGridViewTransactions.Font.Size, FontStyle.Strikeout);
                            if (transactionMasterEntry.Head.Equals("head_expense"))
                            {
                                style.BackColor = Color.PaleVioletRed;
                            }
                            else
                            {
                                style.BackColor = Color.LightGreen;
                            }

                            newRow.DefaultCellStyle.ApplyStyle(style);
                        }

                        forCaching.Add(newRow);

                        newRow.Tag = transactionMasterEntry;
                    }

                    if (this._pagedResultDGViewRowsReconcileView.Count == 5) // kepe just five pages in memory
                    {
                        int minPageNumber = this._pagedResultDGViewRowsReconcileView.Keys.Min();
                        int maxPageNumber = this._pagedResultDGViewRowsReconcileView.Keys.Max();

                        if (_currentPageNumberReconcileView > maxPageNumber)
                        {
                            this._pagedResultDGViewRowsReconcileView.Remove(minPageNumber);
                        }
                        else
                        {
                            this._pagedResultDGViewRowsReconcileView.Remove(maxPageNumber);
                        }
                    }

                    this._pagedResultDGViewRowsReconcileView.Add(_currentPageNumberReconcileView, forCaching);
                }

                if (this.dataGridViewTransactions.Rows.Count > 0)
                {
                    this.dataGridViewTransactions.Rows[0].Selected = true;

                    this.dataGridViewTransactions_Click(this.dataGridViewTransactions, null);

                    this.labelCurentPageNumberDetailsReconcile.Text = string.Format("Page {0}/{1}", (this._currentPageNumberReconcileView + 1), this._currentLastPageNumberReconcileView);
                }
                
                this._isPopulating = false;
            }
            catch { }
            finally 
            {
                this._isPopulating = false;
            }
        }

        private void FetchAndDisplayPagedResultsReconcileView()
        {
            if (this._currentFilterCriteriaReconcileView == null)
            {
                return;
            }

            List<TransactionMaster> result = new List<TransactionMaster>();
            if (_pagedResultReconcileView.ContainsKey(_currentPageNumberReconcileView))
            {
                result.AddRange(_pagedResultReconcileView[_currentPageNumberReconcileView]);
                if (result.Count > 0)
                {
                    this._resultsExistReconcileView = true;
                }
            }
            else
            {
                result.AddRange(
                        this.dataAccessHandlerCommonInstance.GetFilteredTransactionMasterList(_currentFilterCriteriaReconcileView, _currentPageNumberReconcileView, this._currentRecordsPerPageToUseReconcileView, out _currentTotalNumberOfRecordsReconcileView, MainForm.Context));

                if (result.Count > 0)
                {
                    this._resultsExistReconcileView = true;
                }
                else if (result.Count == 0 && !this._resultsExistReconcileView)
                {
                    ResetReconcileView();
                    MessageBox.Show("No results matched your filter criteria.", "No results", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                int remainder = 0;
                this._currentLastPageNumberReconcileView = Math.DivRem(this._currentTotalNumberOfRecordsReconcileView, this._currentRecordsPerPageToUseReconcileView, out remainder);
                if (remainder > 0)
                {
                    this._currentLastPageNumberReconcileView = this._currentLastPageNumberReconcileView + 1;
                }

                if (this._currentLastPageNumberReconcileView == 1)
                {
                    this.buttonPreviousReconcile.Enabled = false;
                    this.buttonNextReconcile.Enabled = false;
                }

                if (result.Count > 0)
                {
                    if (_pagedResultReconcileView.Count == 5) // kepe just five pages in memory
                    {
                        int minPageNumber = _pagedResultReconcileView.Keys.Min();
                        int maxPageNumber = _pagedResultReconcileView.Keys.Max();

                        if (_currentPageNumberReconcileView > maxPageNumber)
                        {
                            _pagedResultReconcileView.Remove(minPageNumber);
                        }
                        else
                        {
                            _pagedResultReconcileView.Remove(maxPageNumber);
                        }
                    }

                    _pagedResultReconcileView.Add(_currentPageNumberReconcileView, result);
                }
            }

            // set current balance
            if (!result.Any(t => !t.IsActive) &&
                (
                 (_currentFilterCriteriaReconcileView.OnlyReconciledRecords && _currentFilterCriteriaReconcileView.BankAccountsIdList.Count == 1) ||
                 (!result.Any(t => !t.BankDate.HasValue) && _currentFilterCriteriaReconcileView.BankAccountsIdList.Count == 1)
                )
               )
            {
                result = this.dataAccessHandlerCommonInstance.SetCurrentBalance(result, true, _currentFilterCriteriaReconcileView.BankAccountsIdList.First(), MainForm.Context);
                _currentFilterCriteriaReconcileView.RunningBalanceComputed = true;
            }

            PopulateReconcileGrid(result);
        }

        #endregion Private Methods

        #region Public Methods
        #endregion Public Methods
    }
}